package com.example.fund.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.example.fund.Constant;
import com.example.fund.updatestategy.FundNetValueUpdateStrategy;
import com.example.fund.updatestategy.UpdateStrategy;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;

public class FundUtil1 {
	private final static DateFormat DF1 = new SimpleDateFormat("yyyy-MM-dd");
	//指数最近一年的价格
	private static Map<String,List<Double>> fundLastHYNetValue = new HashMap<String,List<Double>>();
	
	public static Map<String,Integer> indexColorMap = new HashMap<String,Integer>();
	/**
	 * 计算基金与各指数的相关系数
	 * @param
	 * @param fundNumber
	 * @return
	 */
	public static List<Map.Entry<String,Double>> getCorrel(String fundNumber)
	{
		Map<String,Double> map = new HashMap<String,Double>();
		
        String lastDate = FundUtil.getFundLastDate(fundNumber);
        String shLastDate = FundUtil.getFundLastDate("0000001");
  //      FundUtil.getFundNetValueFromUrl(fundNumber,lastDate,shLastDate);
		UpdateStrategy updateStrategy = new FundNetValueUpdateStrategy(fundNumber);
		updateStrategy.updateIndex();
		List<Double> list = getFundLastHYNetValue(fundNumber);
		
		Map<String,List<Double>> fundLastHYNetValue = getFundLastHYNetValue();
		for(String number:fundLastHYNetValue.keySet())
		{
			List<Double> list1 = fundLastHYNetValue.get(number);
			double v = Similarity.correl(list, list1);
		//	if(v>=0.75)
			{
				map.put(number,v);
			}
		}
		//通过ArrayList构造函数把map.entrySet()转换成list
		List<Map.Entry<String,Double>> mappingList = new ArrayList<Map.Entry<String,Double>>(map.entrySet());
		//通过比较器实现比较排序 
		Collections.sort(mappingList, new Comparator<Map.Entry<String,Double>>(){ 
			public int compare(Map.Entry<String,Double> mapping1,Map.Entry<String,Double> mapping2){ 
				return mapping2.getValue().compareTo(mapping1.getValue()); 
			} 
		}); 
		
		return mappingList;
	}
	
	/**
	 * 从本地加载指数最近半年的价格
	 * @param
	 * @return
	 */
	public static Map<String,List<Double>> getFundLastHYNetValue()
	{
		if(fundLastHYNetValue.size()!=0)
		{
			return fundLastHYNetValue;
		}
		List<Map<String,Object>> indexList = getIndexSet();
	//	for(int i=0;i<Constant.indexNumbers.length;i++)
		for(int i=0;i<indexList.size();i++)
		{
			Map<String, Object> map = indexList.get(i);
			Object numberObj = map.get("number");
			if(numberObj==null || numberObj.toString().trim().length()==0)
			{
				continue;
			}
			String number = numberObj.toString().trim();
			List<Double> list = getFundLastHYNetValue(number);
			fundLastHYNetValue.put(number, list);
		}
		return fundLastHYNetValue;
	}
	
	/**
	 * 从本地加载指数或基金最近半年的价格
	 * @param number
	 */
	public static List<Double> getFundLastHYNetValue(String number)
	{
		SQLiteDatabase db = DBManager.getDB();

		List<Double> list = new LinkedList<Double>();
		
		Calendar c = Calendar.getInstance();
//		c.add(Calendar.MONTH, -6);
		c.add(Calendar.YEAR, -3);
		String date = DF1.format(c.getTime());
		
		String minDate = FundUtil.getFundMinDate(number);
		if(minDate!=null && minDate.trim().length()>0)
		{
			Calendar c1 = Calendar.getInstance();
			try {
				c1.setTime(DF1.parse(minDate));
				c1.add(Calendar.MONTH, 3);
				minDate = DF1.format(c1.getTime());
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
//		String sql = "select netValue from FundNetValue where fundNumber='"+number+"' and date>='"+date+"' and date>='"+minDate+"' order by date desc";
		StringBuffer sql = new StringBuffer();
		sql.append(" select 	\n");
		sql.append("	date,	\n");
		sql.append("	netValue 	\n");
		sql.append(" from FundNetValue 	\n");
		sql.append(" where fundNumber='"+number+"' 	\n");
		sql.append(" and date>='"+date+"' 	\n");
		if(!StringUtil.isNullOrEmpty(minDate))
		{
			sql.append(" and date>='"+minDate+"' 	\n");
		}
		sql.append(" order by date desc			\n");
		Cursor cs = db.rawQuery(sql.toString(), null);
		while (cs.moveToNext())
		{
            double netValue = cs.getDouble(cs.getColumnIndex("netValue"));
            list.add(netValue);
		}
		cs.close();
		
		return list;
	}
	
	/**
	 * 
	 * @param
	 */
	public static List<Map<String,Object>> getIndexSet()
	{
		SQLiteDatabase db = DBManager.getDB();

		List<Map<String,Object>> list = new LinkedList<Map<String,Object>>();
		String sql = "select * from indexset order by enable desc,seq";
		Cursor cs = db.rawQuery(sql.toString(), null);
		
		Set<String> numberSet = new HashSet<String>();
		while (cs.moveToNext())
		{
			int seq = cs.getInt(cs.getColumnIndex("seq"));
            String number = cs.getString(cs.getColumnIndex("number"));
            String name = cs.getString(cs.getColumnIndex("name"));
            String refNumber = cs.getString(cs.getColumnIndex("refNumber"));
            String defDate = cs.getString(cs.getColumnIndex("defDate"));
            int enable = cs.getInt(cs.getColumnIndex("enable"));
            
            HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
            tempHashMap.put("seq", seq);  
            tempHashMap.put("number",number);  
            tempHashMap.put("name", name);  
            tempHashMap.put("refNumber", refNumber);  
            tempHashMap.put("defDate", defDate);  
            tempHashMap.put("enable",enable); 
            list.add(tempHashMap);
            
            numberSet.add(number);
		}
		cs.close();
		
		if(numberSet.size()==0)
		{
			for(int i=0;i<Constant.indexNumbers.length;i++)
			{
				HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
				tempHashMap.put("seq", i);  
				tempHashMap.put("number",Constant.indexNumbers[i][0]);  
				tempHashMap.put("name", Constant.indexNumbers[i][1]);  
				tempHashMap.put("enable",1); 
				tempHashMap.put("refNumber","B"); 
				list.add(tempHashMap);

				numberSet.add(Constant.indexNumbers[i][0]);
			}
		}
		
		if(!numberSet.contains("0000001"))
		{
            HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
            tempHashMap.put("seq", 0);  
            tempHashMap.put("number","0000001");  
            tempHashMap.put("name", "上证");  
            tempHashMap.put("enable",1);
            tempHashMap.put("refNumber","B");
            
            list.add(0, tempHashMap);
		}
		if(!numberSet.contains("0000905"))
		{
            HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
            tempHashMap.put("seq", 0);  
            tempHashMap.put("number","0000905");  
            tempHashMap.put("name", "中证500");  
            tempHashMap.put("enable",1);
            tempHashMap.put("refNumber","B");
            
            list.add(1, tempHashMap);
		}
		if(!numberSet.contains("1399006"))
		{
            HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
            tempHashMap.put("seq", 0);  
            tempHashMap.put("number","1399006");  
            tempHashMap.put("name", "创业板");  
            tempHashMap.put("enable",1);
            tempHashMap.put("refNumber","B");
            
            list.add(2, tempHashMap);
		}
		if(!numberSet.contains("1399102"))
		{
			HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
			tempHashMap.put("seq", 0);  
			tempHashMap.put("number","1399102");  
			tempHashMap.put("name", "创业板综");  
			tempHashMap.put("enable",1);
			tempHashMap.put("refNumber","B");
			
			list.add(3, tempHashMap);
		}
		if(!numberSet.contains("0000000"))
		{
            HashMap<String, Object> tempHashMap = new HashMap<String, Object>();  
            tempHashMap.put("seq", 0);  
            tempHashMap.put("number","0000000");  
            tempHashMap.put("name", "");  
            tempHashMap.put("enable",1);
            tempHashMap.put("refNumber","B");
            
            list.add(tempHashMap);
		}
		
		return list;
	}
	
	/**
	 * 
	 * @param
	 */
	public static Map<String,String> getIndexNameMap()
	{
		SQLiteDatabase db = DBManager.getDB();

		Map<String,String> map = new HashMap<String,String>();
		String sql = "select * from indexset order by seq";
		Cursor cs = db.rawQuery(sql.toString(), null);
		
		Set<String> numberSet = new HashSet<String>();
		while (cs.moveToNext())
		{
            String number = cs.getString(cs.getColumnIndex("number"));
            String name = cs.getString(cs.getColumnIndex("name"));
            
            map.put(number, name); 
            numberSet.add(number);
		}
		cs.close();
		
		map.put("0000001", "上证");  
		map.put("1399006", "创业板"); 
		map.put("1399102", "创业板综"); 
		map.put("0000905", "中证500"); 
		map.put("0000000", ""); 
		
		return map;
	}
	
	/**
	 * 
	 * @param
	 */
	public static Map<String, Integer> getIndexColorMap()
	{
		SQLiteDatabase db = DBManager.getDB();

		if(indexColorMap.size()>0)
		{
			return indexColorMap;
		}
		
		String sql = "select * from indexset order by seq";
		Cursor cs = db.rawQuery(sql.toString(), null);
		
		while (cs.moveToNext())
		{
            String number = cs.getString(cs.getColumnIndex("number"));
            int seq = cs.getInt(cs.getColumnIndex("seq"));
            
            indexColorMap.put(number, Constant.colorSet[seq%Constant.colorSet.length]); 
		}
		cs.close();
		
		return indexColorMap;
	}
	
	public static int getIndexColor(String number)
	{
		Integer color = getIndexColorMap().get(number);
		if(color==null)
		{
			color = Constant.colorSet[0];
		}
		return color;
	}
	
	/**
	 * 保存指数设置
	 * @param
	 * @param list
	 * @return
	 */
	public static boolean saveIndexSet(List<Map<String,Object>> list)
	{
		SQLiteDatabase db = DBManager.getDB();

		String delSql = "delete from indexset";
        StringBuffer insertSql = new StringBuffer();
        insertSql.append("	insert into indexset (	\n");
        insertSql.append("	    id,	\n");
        insertSql.append("	    seq,	\n");
        insertSql.append("	    number,	\n");
        insertSql.append("	    name,	\n");
        insertSql.append("	    enable,	\n");
        insertSql.append("	    refNumber,	\n");
        insertSql.append("	    defDate	\n");
        insertSql.append("	) values (	\n");
        insertSql.append("	    null,	\n");
        insertSql.append("	    ?,	\n");
        insertSql.append("	    ?,	\n");
        insertSql.append("	    ?,	\n");
        insertSql.append("	    ?,	\n");
        insertSql.append("	    ?,	\n");
        insertSql.append("	    ?	\n");
        insertSql.append("	)   	\n");
		
		db.beginTransaction();
		SQLiteStatement stmt = db.compileStatement(insertSql.toString());
		SQLiteStatement stmt1 = db.compileStatement(delSql);
		stmt1.execute();
		
		for(int i=0;i<list.size();i++)
		{
			Map<String,Object> map = list.get(i);
			Object numberObj = map.get("number");
			Object nameObj = map.get("name");
			Object enableObj = map.get("enable");
			Object refNumberObj = map.get("refNumber");
			Object defDateObj = map.get("defDate");
			if(numberObj==null || numberObj.toString().trim().length()==0)
			{
				continue;
			}
			String number = numberObj.toString().trim();
			int seq = i;
			if("0000000".equals(number))
			{
				seq = 999;
			}
		    stmt.bindLong(1, seq);
		    stmt.bindString(2, numberObj.toString().trim());
		    stmt.bindString(3, nameObj==null?"":nameObj.toString().trim());
		    stmt.bindLong(4, (enableObj!=null && "1".equals(enableObj.toString().trim()))?1:0);
		    stmt.bindString(5, refNumberObj==null?"B":refNumberObj.toString().trim());
		    stmt.bindString(6, defDateObj==null || defDateObj.toString().trim().length()!=10?"":defDateObj.toString().trim());
		    stmt.execute();  
		    stmt.clearBindings(); 
		}
		
		db.setTransactionSuccessful();  
		db.endTransaction(); 
		return true;
	}
	
	/**
	 * 保存交易记录
	 * @param
	 * @param
	 * @return
	 */
	public static boolean saveTrade(String number,String date,int type,double tradeAmount)
	{
		if(StringUtil.isNullOrEmpty(number)
				|| StringUtil.isNullOrEmpty(date)
				|| StringUtil.isNullOrEmpty(type))
		{
			return false;
		}
		
		SQLiteDatabase db = DBManager.getDB();

		
        StringBuffer insertSql = new StringBuffer();
        insertSql.append("	insert into fundTrade (	\n");
        insertSql.append("	    id,	\n");
        insertSql.append("	    fundNumber,	\n");
        insertSql.append("	    date,	\n");
        insertSql.append("	    type,	\n");
        insertSql.append("	    account,	\n");
        insertSql.append("	    tradePrice,	\n");
        insertSql.append("	    tradeQty,	\n");
        insertSql.append("	    tradeAmount,	\n");
        insertSql.append("	) values (	\n");
        insertSql.append("	    null,	\n");
        insertSql.append("	    ?,	\n");//1.fundNumber
        insertSql.append("	    ?,	\n");//2.date
        insertSql.append("	    ?,	\n");//3.type
        insertSql.append("	    ?,	\n");//4.account
        insertSql.append("	    (select netValue from FundNetValue where fundNumber=? and date=?),	\n");//5.6.tradePrice
		insertSql.append("	    ?/(select netValue from FundNetValue where fundNumber=? and date=?),	\n");//7.8.9.tradeQty
		insertSql.append("	    ?	\n");//10.tradeAmount
        insertSql.append("	)   	\n");
		
		db.beginTransaction();
		
		if(type==-1)
		{
			String delSql = "delete from fundTrade where fundNumber=?";
			SQLiteStatement stmt1 = db.compileStatement(delSql);
			stmt1.bindString(1, number);
			stmt1.execute();
		}else
		{
			String delSql = "delete from fundTrade where fundNumber=? and date=?";
			SQLiteStatement stmt1 = db.compileStatement(delSql);
			stmt1.bindString(1, number);
		    stmt1.bindString(2, date);
			stmt1.execute();
		}

		
		if(type==1||type==2)
		{
			SQLiteStatement stmt = db.compileStatement(insertSql.toString());
			stmt.bindString(1, number);
			stmt.bindString(2, date);
			stmt.bindLong(3, type);
			stmt.bindString(4, "等风来A");
			stmt.bindString(5, number);
			stmt.bindString(6, date);
			stmt.bindDouble(7, tradeAmount);
			stmt.bindString(8, number);
			stmt.bindString(9, date);
			stmt.bindDouble(10, tradeAmount);
			stmt.execute();
		}
		
		db.setTransactionSuccessful();  
		db.endTransaction(); 
		return true;
	}
	
	/**
	 * 查询交易日期
	 * @param number
	 */
	public static Set<String> getTradeSet(String number,String account,int type)
	{
		SQLiteDatabase db = DBManager.getDB();

		StringBuffer sql = new StringBuffer();
		sql.append(" select date from fundTrade ");
		sql.append(" where fundNumber='"+number+"' ");
		sql.append(" and type= "+type);
		if (!StringUtil.isNullOrEmpty(account))
		{
			sql.append(" and account='"+account+"' ");
		}
		sql.append(" order by date");

		Cursor cs = db.rawQuery(sql.toString(), null);
		
		Set<String> dateSet = new HashSet<String>();
		while (cs.moveToNext())
		{
            String date = cs.getString(cs.getColumnIndex("date"));
            dateSet.add(date);
		}
		cs.close();
		
		return dateSet;
	}
	
	
	/**
	 * 查询交易类型
	 * @param number
	 */
	public static int getTradeType(String number,String date)
	{
		SQLiteDatabase db = DBManager.getDB();

		Map<String,String> map = new HashMap<String,String>();
		String sql = "select type from fundTrade where fundNumber='"+number+"' and date= '"+date+"'";
		Cursor cs = db.rawQuery(sql.toString(), null);
		
		int type = 0;
		while (cs.moveToNext())
		{
            type = cs.getInt(cs.getColumnIndex("type"));
		}
		cs.close();
		
		return type;
	}
	
	/**
	 * 删除指数
	 * @param db
	 * @param
	 * @return
	 */
	public static boolean delIndexSet(SQLiteDatabase db,String number)
	{
		if("0000001".equals(number) || "0000905".equals(number)
				|| "1399006".equals(number) || "1399102".equals(number) || "0000000".equals(number))
		{
			return false;
		}
		
		String sqlDel = "delete from indexset where number='"+number+"'";
		db.execSQL(sqlDel);
		return true;
	}

/*	public static String test(SQLiteDatabase db,String number)
	{
		
		List<Map.Entry<String,Double>> mappingList = FundUtil1.getCorrel(db,number);
		int i=0;
		String text = "";
		for(Map.Entry<String,Double> mapping:mappingList)
		{ 
			if(i==0)
			{
				text = Constant.indexNamesMap.get(mapping.getKey())+"("+mapping.getValue()+")";
			}else
			{
				text = text+" "+Constant.indexNamesMap.get(mapping.getKey())+"("+mapping.getValue()+")";
				
			}
			i++;
		}
		return text;
	}*/
}
